﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using GTA.Common.Log;
using System.Threading;
using System.Collections;

namespace GTA.Common.Controls
{
    public partial class LogViewer : UserControl
    {
        private bool _enableDisplay = true;
        /// <summary>
        /// 是否允许显示信息
        /// </summary>
        public bool EnableDisplay
        {
            get
            {
                return _enableDisplay;
            }
            set
            {
                _enableDisplay = value;
            }
        }

        private bool _isProcessing;

        public LogViewer()
        {
            InitializeComponent();
        }

        private Queue<MessageEventArgs> _queue = new Queue<MessageEventArgs>();

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            Logger.Instance.TraceOut += new EventHandler<MessageEventArgs>(Instance_TraceOut);
        }

        void Instance_TraceOut(object sender, MessageEventArgs e)
        {
            if (!this.EnableDisplay)
            {
                return;
            }
            lock (
                ((ICollection)_queue).SyncRoot)
            {
                this._queue.Enqueue(e);
            }
            lock (this)
            {
                if (!_isProcessing)
                {
                    _isProcessing = ThreadPool.QueueUserWorkItem(ProcessQueue);
                }
            }
        }

        private void ProcessQueue(object o)
        {
            while (_queue.Count > 0)
            {
                MessageEventArgs e = null;
                lock (
                    ((ICollection)_queue).SyncRoot)
                {
                    e = _queue.Dequeue();
                }
                if (e == null)
                {
                    continue;
                }
                AppendMessage(e);
            }
            lock (this)
            {
                _isProcessing = false;
            }
        }

        private void AppendMessage(MessageEventArgs e)
        {
            if (e == null || this.richTextBox1.IsDisposed)
            {
                return;
            }
            if (this.richTextBox1.InvokeRequired)
            {
                this.richTextBox1.Invoke(new MethodInvoker(() => { AppendMessage(e); }));
                return;
            }
            string message = string.Format("{0:HH:mm:ss.fff} [{1}] {2}\r\n", e.MessageTime, e.Level, e.Message);
            if (this.richTextBox1.MaxLength < this.richTextBox1.TextLength + message.Length)
            {
                this.richTextBox1.Clear();
            }
            this.richTextBox1.SelectionColor = GetMessageColor(e.Level);
            this.richTextBox1.AppendText(message);
        }

        private Color GetMessageColor(MessageLevel level)
        {
            switch (level)
            {
                case MessageLevel.DEBUG:
                    return Color.Black;

                case MessageLevel.ERROR:
                    return Color.Red;

                case MessageLevel.FATAL:
                    return Color.Red;

                case MessageLevel.INFO:
                    return Color.Blue;

                case MessageLevel.WARN:
                    return Color.Orange;

                default:
                    return Color.Black;
            }
        }

        private void clearToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.richTextBox1.Clear();
        }
    }
}
